package com.dsunsoft.rtu.common.util;

import com.dsunsoft.rtu.common.constant.CommonConstants;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

/**
 * 工具类
 */
public class CommonUtils {

    /**
     * 获取uuid
     */
    public static String getUuid() {
        return UUID.randomUUID().toString();
    }

    /**
     * 字符串转hex字符串
     *
     * @param str
     * @return
     */
    public static String strToHexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder();
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            // sb.append(' ');
        }
        return sb.toString().trim();
    }

    /**
     * Hex转byte[]，两种情况，Hex长度为奇数最后一个字符会被舍去
     */
    public static byte[] hexToBytes(String hex) {
        if (StringUtils.isBlank(hex)) {
            hex = "00";
        }
        int j = 0;
        byte[] returnBytes = new byte[hex.length() / 2];
        for (int i = 0; i < hex.length(); i += 2) {
            returnBytes[j++] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
        }
        return returnBytes;
    }

    /**
     * 字节转hex字符串
     *
     * @param src 字节数据
     * @return hex
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return CommonConstants.EMPTY;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 16进制直接转换成为字符串
     *
     * @param hexStr
     * @return
     */
    public static String hexStrToStr(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 数字转16进制, 用0补齐4位字符
     *
     * @param input
     * @return
     */
    public static String intToHexString(int input) {
        return String.format("%04x", input);
    }

    /**
     * 获取当前时间的16进制组合指令拼接
     */
    public static String getCurrentTimeOfRTU(){
        Calendar calendar = Calendar.getInstance();
        String year = String.format("%04x", calendar.get(Calendar.YEAR));
        String month = String.format("%02x", calendar.get(Calendar.MONTH));
        String dayOfMonth = String.format("%02x", calendar.get(Calendar.DAY_OF_MONTH));
        String hourOfDay = String.format("%02x", calendar.get(Calendar.HOUR_OF_DAY));
        String minute = String.format("%02x", calendar.get(Calendar.MINUTE));
        String second = String.format("%02x", calendar.get(Calendar.SECOND));
        return  (year + month + dayOfMonth + hourOfDay + minute + second).toUpperCase();
    }


    /**
     * 32位md5加密
     *
     * @param input 字符串
     * @return 加密后的字符串
     */
    public static String md5(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] result = digest.digest(input.getBytes());
            StringBuffer buffer = new StringBuffer();
            // 把每一个byte 做一个与运算 0xff;
            for (byte b : result) {
                // 与运算
                int number = b & 0xff;// 加盐
                String str = Integer.toHexString(number);
                if (str.length() == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }
            // 标准的md5加密后的结果
            return buffer.toString();
        } catch (Exception e) {
            return CommonConstants.EMPTY;
        }
    }

    public static void main(String[] args) {
        // 97 96 00 07 00 0B 07 03 08 00 05 00 00 00 00 00 86
        String hexData = "97960007000B0703080005000000000086";
        System.out.println("16进制报文: " + hexData);
        String deviceNo = hexData.substring(4, 8);
        System.out.println("[设备编号] 16进制: " + deviceNo + ",10进制: " + Integer.parseInt(deviceNo, 16));
        String drp = hexData.substring(18, 22);
        System.out.println("[间隔时间降雨] 16进制: " + drp + ",10进制: " + Integer.parseInt(drp, 16) + ",翻转毫米: " + Integer.parseInt(drp, 16) * 0.5d);
        String drp1 = hexData.substring(22, 26);
        System.out.println("[1小时降雨量] 16进制: " + drp1 + ",10进制: " + Integer.parseInt(drp1, 16) + ",翻转毫米: " + Integer.parseInt(drp1, 16) * 0.5d);
        String drp24 = hexData.substring(26, 30);
        System.out.println("[24小时降雨量] 16进制: " + drp24 + ",10进制: " + Integer.parseInt(drp24, 16) + ",翻转毫米: " + Integer.parseInt(drp24, 16) * 0.5d);
        String voltage = hexData.substring(30, 34);
        System.out.println("[电压] 16进制: " + voltage + ",10进制: " + Integer.parseInt(voltage, 16) / 10d);

        String asciiStr = "7777772E7573722E636E";
        System.out.println(hexStrToStr(asciiStr));

        String hex = "3130303030303030303030303030";
        String hex1 = "970000010009686561727462656174";
        System.out.println(CommonUtils.hexStrToStr(hex));
        System.out.println(CommonUtils.hexStrToStr(hex1));
        System.out.println("heartbeat".getBytes(StandardCharsets.US_ASCII).length);
        System.out.println("10转16进制" + String.format("%04x", 12));
        System.out.println("10转16进制" + StringUtils.leftPad(Integer.toHexString(12), 4, '0'));
        System.out.println("9796000D000A17030601030400000384".substring(24,32));
        System.out.println("9796000D000C17030901030400AE01B89A30".substring(24,32));


        Calendar calendar = Calendar.getInstance();

        String year = String.format("%04x", calendar.get(Calendar.YEAR));

        String month = String.format("%02x", calendar.get(Calendar.MONTH));

        String dayOfMonth = String.format("%02x", calendar.get(Calendar.DAY_OF_MONTH));

        String hourOfDay = String.format("%02x", calendar.get(Calendar.HOUR_OF_DAY));

        String minute = String.format("%02x", calendar.get(Calendar.MINUTE));
        String second = String.format("%02x", calendar.get(Calendar.SECOND));

        System.out.println((year + month + dayOfMonth + hourOfDay + minute + second).toUpperCase());
        System.out.println(CommonUtils.getCurrentTimeOfRTU());


    }
}
